#pragma once

#include <iostream>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/int32.hpp"
#include <boost/signals2/signal.hpp>
#include <boost/bind/bind.hpp>
#include <string>
#include "example_interfaces/srv/add_two_ints.hpp"

using namespace std;

namespace my_math_lib{

    template <typename T>
    class Complex{
        friend ostream& operator<<(ostream &out, Complex &c)
        {
            out<<c.a << " + " << c.b << "i";
            return out;
        }
    private:
        T a;
        T b;

    public:
        Complex(T a, T b){
            this->a = a;
            this->b = b;
        };

        Complex<T> operator+(Complex &c)
        {
            Complex<T> tmp(this->a+c.a, this->b+c.b);
            return tmp;
        }
    };
}// namespace my_math_lib

 namespace gui{

// interface里的函数必须是纯虚函数，为了让继承者强制实现
 class Interface{
 public:
     virtual void on_pass_arg(int x, std::string str) = 0; // pure virtual function
     virtual void on_heartbeat() = 0;
 };

 class Client
 {
   public:
     typedef boost::signals2::signal<void(int,std::string)> VIS_signal; // Void(Int, String) = VIS
     typedef VIS_signal::slot_type VIS_slotType;

     typedef boost::signals2::signal<void()> V_signal;
     typedef V_signal::slot_type V_slotType;

     Client();
     // Service
     int get_sum(int a, int b);
     std::shared_ptr<rclcpp::Node> get_node(){
       return node_;
     }

     // Topic 的回调
     boost::signals2::connection connect_pass_arg_func(const VIS_slotType& slot);
     boost::signals2::connection connect_heartbeat_func(const V_slotType& slot);

   private:
     void topic_callback(std_msgs::msg::Int32::SharedPtr msg) const;
     VIS_signal signal_pass_arg;
     V_signal signal_heartbeat;
     std::shared_ptr<rclcpp::Node> node_;
     rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr subscription_;
     rclcpp::Client<example_interfaces::srv::AddTwoInts>::SharedPtr add_client_;
 };
 }